package com.hc.api.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.hc.api.enums.GoodsEnum;
import com.hc.api.enums.ShareStateEnum;
import com.hc.api.model.WXUserInfoModel;
import com.hc.api.utils.ApiUtil;
import com.hc.api.utils.ShareConfigUtils;
import com.hc.api.utils.TokenUtils;
import com.hc.comm.base.BaseController;
import com.hc.comm.dto.ShareDTO;
import com.hc.comm.dto.ShareRecordDTO;
import com.hc.comm.dto.VoucherDataDTO;
import com.hc.comm.dto.WxShareInfoDTO;
import com.hc.comm.utils.JsonUtils;
import com.hc.comm.utils.StringUtil;
import com.hc.comm.vo.ShareVO;
import com.hc.service.model.ShareModel;
import com.hc.service.model.ShareRecordModel;
import com.hc.service.model.VoucherDataModel;
import com.hc.service.model.WxShareInfoModel;
import com.hc.service.service.IShareRecordService;
import com.hc.service.service.IShareService;
import com.hc.service.service.IVoucherDataService;
import com.hc.service.service.IWxShareInfoService;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.annotation.Resource;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;

/**
 * Created by yx on 2017/4/20.
 */
@Controller
@Scope("prototype")
@RequestMapping("/" + ApiUtil.ApiVersion.V1 + "/share/")
public class ShareController extends BaseController {

    @Resource(name = "shareService")
    private IShareService shareService;

    @Resource(name = "shareRecordService")
    private IShareRecordService shareRecordService;

    @Resource(name = "voucherDataService")
    private IVoucherDataService voucherDataService;

    @Resource(name = "wxShareInfoService")
    private IWxShareInfoService wxShareInfoService;

    /**
     * 第一个用户从app分享获取，分享优惠券的url
     * objecteId   物品的id
     * unionId    第三方unionid,唯一性id
     * openId   openId
     * platform 分享的平台,1微信,2qq,3微博
     * userId   app用户id
     */
    @RequestMapping("getShareVoucherURL")
    public void getShareURL(@ModelAttribute ShareDTO shareDTO,
                            @ModelAttribute ShareRecordDTO shareRecordDTO) throws Exception {
        if (shareRecordDTO == null
                || StringUtils.isEmpty(shareRecordDTO.getOpenId())
                || shareRecordDTO.getPlatform() == null
                || shareDTO == null
                || shareDTO.getObjecteId() == null) {
            JsonUtils.toErrorResult(request, response, "参数异常!");
        } else {
            //只考虑分享优惠券的
            shareDTO.setObjectType(GoodsEnum.VOUCHER.getCode());
            VoucherDataDTO voucherDataDTO = new VoucherDataDTO();
            voucherDataDTO.setId(shareDTO.getObjecteId());
            VoucherDataModel voucherDataModel = voucherDataService.getOne(voucherDataDTO);
            if (voucherDataModel == null) {
                JsonUtils.toErrorResult(request, response, "没有此优惠券!");
                return;
            }
            //从客户端分享生成一条数据
            ShareModel shareModel;
            shareModel = checkOneShare(shareRecordDTO.getOpenId(), shareDTO.getObjecteId());
            if (shareModel == null) {
                shareModel.setObjectType(GoodsEnum.VOUCHER.getCode());
                shareModel.setObjecteId(voucherDataModel.getId());
                shareModel.setCreateTime(new Long(System.currentTimeMillis() / 1000).intValue());
                shareModel.setShareContent(voucherDataModel.getVoucherDescription());
                shareModel.setShareTitle("我有一张优惠券要分享");
                shareModel.setShareState(ShareStateEnum.NORMAL.getCode());
                shareModel.setShareImage(voucherDataModel.getVoucherIcon());
                int startTime = new Long(System.currentTimeMillis() / 1000).intValue(); //分享开始时间
                shareModel.setStartTime(startTime);
                int endTime = startTime + 30 * 24 * 60 * 60; //30天有效期
                shareModel.setEndTime(endTime);
                String shareUrl = "http://share.tunnel.2bdata.com/V1/share/shareVoucher";
                shareModel.setShareUrl(shareUrl);
                shareModel.setProfit(10.00);
                //分享内容表
                shareModel = shareService.insert(shareModel);
            }
            //生成分享记录,只有成功后存入token才有效
            //每次生成分享记录不同，会生成新的token
            //但是只有回调回来保存了token的记录才是生效记录
            ShareRecordModel shareRecordModel = new ShareRecordModel();
            shareRecordModel.setCreateTime(new Long(System.currentTimeMillis() / 1000).intValue());
            shareRecordModel.setContentId(shareModel.getId());
            shareRecordModel.setPlatform(shareRecordDTO.getPlatform());
            shareRecordModel.setShareTime(new Long(System.currentTimeMillis() / 1000).intValue());
            shareRecordModel.setFromId(0);
            shareRecordModel.setUnionId(shareRecordDTO.getUnionId());
            shareRecordModel.setOpenId(shareRecordDTO.getOpenId());
            shareRecordModel = shareRecordService.insert(shareRecordModel);
            String shareToken = TokenUtils.generateShareToken(shareRecordModel.getId());
            System.out.println("shareTokne:" + shareToken);
            ShareVO shareVO = new ShareVO();
            shareVO.copyPropertis(shareModel);
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(shareModel.getShareUrl() + "?shareToken=");
            stringBuilder.append(shareToken);
            shareVO.setShareUrl(stringBuilder.toString());
            JsonUtils.toSuccessResult(request, response, shareVO,
                    "shareUrl", "shareImage", "shareTitle", "shareContent",
                    "objectType", "objecteId", "profit", "startTime", "endTime");
        }
    }

    /**
     * 检查用户是否已经分享过同一个优惠券
     * 一个人只可以只算分享一次一个物品
     * 但是多个人可以分享同一个物品
     *
     * @param openId
     * @param ObjectId
     */
    private ShareModel checkOneShare(String openId, int ObjectId) throws Exception {
        ShareDTO shareDTO = new ShareDTO();
        shareDTO.setObjectType(GoodsEnum.VOUCHER.getCode());
        shareDTO.setObjecteId(ObjectId);
        List<ShareModel> shareModelList = shareService.getList(shareDTO);
        if (shareModelList == null || shareModelList.isEmpty()) {
            return null;
        }
        ShareRecordDTO shareRecordDTO = new ShareRecordDTO();
        shareRecordDTO.setOpenId(openId);
        List<ShareRecordModel> shareRecordModelList = shareRecordService.getList(shareRecordDTO);
        if (shareRecordModelList == null || shareRecordModelList.isEmpty()) {
            return null;
        }
        for (ShareRecordModel recordModel : shareRecordModelList) {
            for (ShareModel shareModel : shareModelList) {
                if (recordModel.getContentId() == shareModel.getId()) {
                    return shareModel;
                }
            }
        }
        return null;
    }

    /**
     * third step
     * 分享出去的url进入的这个方法
     *
     * @return
     * @throws Exception
     */
    @RequestMapping("voucher")
    public String shareVoucher() throws Exception {
        System.out.println("voucher------进入分享!");
        String openid = request.getParameter("openid");
        System.out.println("openid:" + openid);
        String unionid = (String) request.getAttribute("unionid");
        String shareUrl = request.getParameter("shareUrl");
        if (StringUtil.isEmpty(openid)) {
            JsonUtils.toErrorResult(request, response, "分享失败!");
        } else {
            try {
                WxShareInfoModel wxShareInfoModel = getWxShareToken();
                if (wxShareInfoModel != null && !StringUtil.isEmpty(wxShareInfoModel.getJsapiTicket())) {
                    String jsapi_ticket = wxShareInfoModel.getJsapiTicket();
                    //生成签名的url应该为打开的页面的url
                    StringBuffer fullUrl = request.getRequestURL();  //请求路径
                    String queryString = request.getQueryString();  //查询参数
                    if (StringUtil.isNotEmpty(queryString)) {
                        fullUrl.append("?");
                        fullUrl.append(queryString);
                    }
                    Map<String, String> ret = ShareConfigUtils.signWX(jsapi_ticket, fullUrl.toString());
                    for (Map.Entry entry : ret.entrySet()) {
                        request.setAttribute(entry.getKey() + "", entry.getValue());
                        System.out.println(entry.getKey() + ", " + entry.getValue());
                    }
                    request.setAttribute("appId", ShareConfigUtils.getWXAppId());
                    request.setAttribute("openid", openid);
                    request.setAttribute("unionid", unionid);
                    request.setAttribute("shareUrl", shareUrl);
                    System.out.println("新的分享鏈接：" + fullUrl.toString());
                } else {
                    JsonUtils.toErrorResult(request, response, "授权失败!");
                }
            } catch (Exception e) {
                JsonUtils.toErrorResult(request, response, "授权失败!");
            }
        }
        return "wxshare/share";
    }

    /**
     * 获取存储的本地的微信的token和jsapi_ticket
     *
     * @return
     * @throws Exception
     */
    private WxShareInfoModel getWxShareToken() throws Exception {
        int authTime = 2 * 60 * 60;//两个小时
        WxShareInfoDTO wxShareInfoDTO = new WxShareInfoDTO();
        wxShareInfoDTO.setSort("requestTime");
        wxShareInfoDTO.setRows(1);
        wxShareInfoDTO.setOrderBy("requestTime");
        WxShareInfoModel wxShareInfoModel = wxShareInfoService.getOne(wxShareInfoDTO);
        if (wxShareInfoModel == null
                || (wxShareInfoModel.getRequestTime() + authTime) < (System.currentTimeMillis() / 1000)) {
            String auth = ShareConfigUtils.getWXShareAuth();
            System.out.println("第一步获取access_token:" + auth);
            JSONObject jsonObject = JSONObject.parseObject(auth);
            if (jsonObject.containsKey("access_token")) {
                String access_token = jsonObject.getString("access_token");
                String signatureStr = ShareConfigUtils.getWXJsApiTicket(access_token);
                System.out.println("第二步获取签名：" + signatureStr);
                JSONObject signJson = JSONObject.parseObject(signatureStr);
                if (signJson.containsKey("ticket")) {
                    String jsapi_ticket = signJson.getString("ticket");
                    wxShareInfoModel = new WxShareInfoModel();
                    wxShareInfoModel.setAccessToken(access_token);
                    wxShareInfoModel.setJsapiTicket(jsapi_ticket);
                    wxShareInfoModel.setRequestTime(new Long(System.currentTimeMillis() / 1000).intValue());//请求的时间
                    wxShareInfoModel = wxShareInfoService.insert(wxShareInfoModel);
                }
            }
        }
        return wxShareInfoModel;
    }

    /**
     * second step
     * 微信分享第一步先获取微信用户信息
     * 将微信用户信息回调给，分享接口
     *
     * @throws Exception
     */
    @RequestMapping("userInfo")
    public String getWXUserInfo(RedirectAttributes attributes) throws Exception {
        System.out.println("userInfo-------获取用户信息!");
//        System.out.println("code:" + request.getParameter("code")
//                + "---state:" + request.getParameter("state"));
        String wxCode = request.getParameter("code");
        String redURL = "redirect:voucher";
        //用户授权时附带的信息
        String wxState = request.getParameter("state");
        if (StringUtil.isEmpty(wxCode)) {
            System.out.println("微信授权失败!");
            JsonUtils.toErrorResult(request, response, "微信授权失败!");
        } else {
            ShareRecordModel shareRecordModel = null;
            if (wxState != null && !StringUtil.isEmpty(wxState) && wxState.contains("-")) {
                System.out.println("state:" + wxState);
                String recodId = wxState.split("-")[0];
                System.out.println("分享记录recodId:" + recodId);
                ShareRecordDTO shareRecordDTO = new ShareRecordDTO();
                shareRecordDTO.setId(Integer.valueOf(recodId));
                shareRecordModel = shareRecordService.getOne(shareRecordDTO);
                if (shareRecordModel != null) {
                    shareRecordModel.setShareToken(wxState);
                    shareRecordService.updateByPrimaryKey(shareRecordModel);
                }
            }
            //用code获取access_token
            String wxAuth = ShareConfigUtils.getWXOAUTHCode(wxCode);
            JSONObject jsonObject = JSONObject.parseObject(wxAuth);
            String access_token = jsonObject.getString("access_token");
            int expires_in = jsonObject.getIntValue("expires_in");
            String openid = jsonObject.getString("openid");
            String refresh_token = jsonObject.getString("refresh_token");
            String scope = jsonObject.getString("scope");
            if (!StringUtils.isEmpty(access_token) && !StringUtil.isEmpty(openid)) {
                //获取用户信息
                String wxUserInfo = ShareConfigUtils.getWXUserInfo(access_token, openid);
                System.out.println("微信用户信息：" + wxUserInfo);

                //如果用户关注公众号可以获取union_id
                WXUserInfoModel wxUserInfoModel = JSON.parseObject(wxUserInfo, WXUserInfoModel.class);
                ShareRecordModel newRecordModel = new ShareRecordModel();
                if (shareRecordModel != null && wxUserInfoModel != null
                        && shareRecordModel.getOpenId().equals(wxUserInfoModel.getOpenid())) {
                    //如果是同一个微信用户不新生成记录
                    newRecordModel = shareRecordModel;
                } else if (shareRecordModel != null) {
                    newRecordModel.setFromId(shareRecordModel.getId());
                    newRecordModel.setOpenId(wxUserInfoModel.getOpenid());
                    newRecordModel.setUnionId(wxUserInfoModel.getUnionid());
                    newRecordModel.setContentId(shareRecordModel.getContentId());
                    newRecordModel.setPlatform(shareRecordModel.getPlatform());
                    newRecordModel.setShareTime(new Long(System.currentTimeMillis() / 1000).intValue());
                    newRecordModel.setCreateTime(new Long(System.currentTimeMillis() / 1000).intValue());
                    newRecordModel = shareRecordService.insert(newRecordModel);
                }
                ShareDTO shareDTO = new ShareDTO();
                shareDTO.setId(shareRecordModel.getContentId());
                ShareModel shareModel = shareService.getOne(shareDTO);
                if (shareModel != null && newRecordModel != null) {
                    String newShareUrl = shareModel.getShareUrl() +
                            "?shareToken=" + TokenUtils.generateShareToken(newRecordModel.getId());
                    if (wxUserInfoModel != null && StringUtil.isNotEmpty(wxUserInfoModel.getOpenid())) {
                        redURL += "?openid=" + wxUserInfoModel.getOpenid()
                                + "&shareUrl=" + URLEncoder.encode(newShareUrl, "utf-8")
                                + "&unionid=" + wxUserInfoModel.getUnionid();
                        System.out.println("冲定向url:" + redURL);
                    }
                }
            }
        }
        return redURL;

    }

    /**
     * first step
     * 微信授权,点击分享的页面后进入
     *
     * @throws Exception
     */
    @RequestMapping("shareVoucher")
    public String getWxAuth(@ModelAttribute ShareRecordDTO shareRecordDTO)
            throws Exception {
        System.out.println("-----shareVoucher");
        String state = "100000";
        if (shareRecordDTO != null && !StringUtil.isEmpty(shareRecordDTO.getShareToken())) {
            state = shareRecordDTO.getShareToken();
        }
        String encodeurl = URLEncoder.encode("http://share.tunnel.2bdata.com/V1/share/userInfo", "UTF-8");
        System.out.println(encodeurl);
        String reURL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid="
                + ShareConfigUtils.getWXAppId()
                + "&redirect_uri=" + encodeurl
                + "&response_type=code&scope=" + ShareConfigUtils.getWxSNSScope()
                + "&state=" + state + "#wechat_redirect";
        System.out.println(reURL);
        return "redirect:" + reURL;
    }

    public static void main(String[] args)
            throws Exception {

    }
}